home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / gle / util / surf / edt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-29  |  20.5 KB  |  1,040 lines

  1. #include "all.h"
  2. #include <errno.h>
  3. #include <math.h>
  4. #ifdef __TURBOC__
  5. #define HLINECHAR 205
  6. #include "bios.h"
  7. #include "conio.h"
  8. #else
  9. #define ENOFILE 999
  10. #define HLINECHAR '-'
  11. #include "vaxconio.h"
  12. #endif
  13. #include "edt.h"
  14. int vax_edt(char *s);
  15. int delay(int i);
  16. extern int gle_debug;
  17. int gle_speed;
  18. int gle_nspeed;
  19. int trace_on;
  20. #define true (!false)
  21. #define false 0
  22. #define dbg if (gle_debug>0)
  23. long mem_total(void);
  24. int pick_file(char *r, char *w);
  25. typedef char (*TEXT)[];
  26. int scr_blackwhite;
  27. int scr_left(int i);
  28. int scr_right(int i);
  29. int scr_norm(void);
  30. int scr_inv(void);
  31. int scr_grey(void);
  32. int text_search(void);
  33. int text_deleol(void);
  34. int text_undeleol(void);
  35. extern int ngerror;
  36. int scr_savexy(void);
  37. int scr_restorexy(void);
  38. int scr_gets(char *s);
  39. int text_showerror(void);
  40. int text_findnext(void);
  41. int text_changed(void);
  42. int read_command(char *ans, char *ques);
  43. int read_str(char *s);
  44. int text_load(char *fname);
  45. int text_free(void);
  46. int do_help(char *s);
  47. int int_edt(char *fname);
  48. int vinsert(int y, char *s);
  49. int vdelete(int y);
  50. int menu(void);
  51. int gle_redraw(void);
  52. int scrinsert(int y);
  53. int scrdeleteline(int y);
  54. int text_save(void);
  55. int text_eol(void);
  56. int text_delright(void);
  57. int text_delete(void);
  58. int text_undelete(void);
  59. int text_deleteline(void);
  60. int text_left(void);
  61. int text_right(void);
  62. int text_up(void);
  63. int text_down(void);
  64. int text_return(void);
  65. int text_refresh();
  66. int text_putstr(char *s);
  67. int text_setwindow();
  68. int text_saveas(void);
  69. int text_move(int x,int y);
  70. int scr_tab(char *s, int x);
  71. int scr_negtab(char *s, int x, int *fpos, int *scrx);
  72. int fner(char *s);
  73. int fner_clear(void);
  74. int text_setwindow(void);
  75. int text_refresh(void);
  76. int text_main(void);
  77. int text_inkey(void);
  78. int text_scroll(void);
  79. int text_scroll_up(void);
  80. int text_scroll_down(void);
  81. int text_select(void);
  82. int text_cut(void);
  83. int text_paste(void);
  84. int restofline(int y,int x);
  85. int normal_key(int c);
  86. int lineset(int i,char *ss);
  87. int lineinsert(int y, char *ss);
  88. int textinsert(int y);
  89. char *sline(int i);
  90. char *line(int i);
  91. int ncpy(char *d, char *s, int n);
  92. /*------------ GLOBAL VARIABLES --------------*/
  93. extern long gtotalmem;
  94. int max_ngtxt;
  95. extern int ngtxt;
  96. extern char *(*gtxt)[];   /* gtxt is a pointer to an array of poiter to char */
  97. char *(*ctxt)[];    /* cut buffer */
  98. int ncut;
  99. int iserr;
  100. int w_top=0,w_bot=0,w_len,w_cl,w_cx;
  101. #define MAXLINES (max_ngtxt-10)
  102. extern int ngtxt;
  103. int move_pos,onmove;
  104. int ii;
  105. char gbuff[255];
  106. char gbuff2[255];
  107. int selx,sely;
  108. extern char input_file[];
  109. int changed;
  110. int scr_isblackwhite(void);
  111. extern int netxt;    /* errors which occured */
  112. extern char *(*etxt)[];
  113. /*---------------------------------------------------------------------------*/
  114. /* copy gtxt, ngtxt   to local paramters */
  115. int tfx,tfy;
  116. int_edt(char *fname)
  117. {
  118.     int i,j;
  119.  
  120.     tfx = 1;
  121.     tfy = 1;
  122.     w_len = 20;
  123.     scr_blackwhite = scr_isblackwhite();
  124.     text_setwindow();
  125.     text_refresh();
  126.     text_main();
  127. }
  128. vinsert(int y,char *ss)
  129. {
  130.     int i;
  131.     if (ngtxt>(max_ngtxt-50)) text_expand(2*(ngtxt+50));
  132.     if (ngtxt>MAXLINES) {fner("too many lines in file "); return;}
  133.     ngtxt++;
  134.     for (i=ngtxt;i>y;i--)
  135.         (*gtxt)[i] = (*gtxt)[i-1];
  136.     (*gtxt)[y] = sdup(ss);
  137. }
  138. lineinsert(int y,char *ss)
  139. {
  140.     vinsert(y,ss);
  141.     scrinsert(y);
  142. }
  143.  
  144. vdelete(int y)
  145. {
  146.     int i;
  147.     if (ngtxt==0) {fner("too few lines in file "); return;}
  148.     ngtxt--;
  149.     myfrees((*gtxt)[y],"vdelete");
  150.     for (i=y;i<=ngtxt;i++)
  151.         (*gtxt)[i] = (*gtxt)[i+1];
  152. }
  153. linedelete(int y)
  154. {
  155.     vdelete(y);
  156.     scrdeleteline(y);
  157. }
  158. lineset(int i,char *ss)
  159. {
  160.     char *zzz;
  161.     int same;
  162.     char *d=(*gtxt)[i];
  163.     char *s=ss;
  164.     if (d==0) gle_abort("linset zero\n");
  165.     for (;*d!=0 && *s!=0 && *d==*s ;s++,d++) ;
  166.     same = s-ss;
  167.     myfrees((*gtxt)[i],"Linset");
  168.     zzz = sdup(ss);
  169.     (*gtxt)[i] = zzz;
  170.     restofline(i,same);
  171. }
  172. char *line(int i)
  173. {
  174.     static char xxx[2]="";
  175.     static char eob[7]="[EOB]";
  176.     if (i>ngtxt) {
  177.         if (i==ngtxt+1) return &eob[0];
  178.         else return &xxx[0];
  179.     }
  180.     return (*gtxt)[i];
  181. }
  182. text_free(void)
  183. {
  184.     int i;
  185.     for (i=1;i<=ngtxt;i++) myfrees( (*gtxt)[i] ,"textfree");
  186.     ngtxt = 0;
  187. }
  188. char *tabtospace(char *s);
  189. char *sline(int i)
  190. {
  191.     return tabtospace(line(i));
  192. }
  193. char *tabtospace(char *s)
  194. {
  195.     static char buf[255];
  196.     char *o = &buf[0];
  197.     int p=0,k,df;
  198.     for (;*s!=0;s++) {
  199.         if (*s==9) {
  200.             df = (p/8)*8+8-p;
  201.             for (k=1;k<=df;k++) {
  202.                 *o++ = ' ';
  203.                 p++;
  204.             }
  205.         } else {
  206.             *o++ = *s;
  207.             p++;
  208.         }
  209.     }
  210.     *o = 0;
  211.     return &buf[0];
  212. }
  213. text_main()
  214. {
  215.     int c,doask;
  216.     for (;;) {
  217.      doask = true;
  218.      c = text_inkey();
  219.      if (iserr) fner_clear();
  220.      switch (c) {
  221.        case eexitnow:
  222.         doask = false;
  223.        case eescape:
  224.        case equit: /* control c */
  225.         if (text_changed()) break;
  226.         if (doask) {
  227.           fner("Exit from SURFACE ? (Y,N)  [y]");
  228.           c = text_inkey();
  229.           fner_clear();
  230.           if (tolower(c)=='n') break;
  231.           if (tolower(c)!='y' && c != ereturn) break;
  232.         }
  233.         window(1,1,80,25);
  234.         scr_norm();
  235.         clrscr();
  236.         return;
  237.        case eedt: /* call edt editor */
  238.         text_save();
  239.         clrscr();
  240.         fner("Entering VAX EDT");
  241.         scr_refresh();
  242.         vax_edt(input_file);
  243.         text_free();
  244.         text_load(input_file);
  245.         text_setwindow();
  246.         text_refresh();
  247.         break;
  248.        case efast:
  249.         gle_speed++;
  250.         if (gle_speed>=gle_nspeed) gle_speed = 0;
  251.         sprintf(gbuff,"Speed of display set to {%d}",gle_speed);
  252.         fner(gbuff);
  253.         break;
  254.        case eleft: /* left */
  255.         text_left();
  256.         break;
  257.        case eshell: /* shell, start a subprocess */
  258.         window(1,1,80,25); scr_norm(); clrscr();
  259.         printf("Type in EXIT to return to SURFACE\n\n");
  260.         system("");
  261.         text_refresh();
  262.         break;
  263.        case etrace: /* trace */
  264.         fner("Trace is now ON (or off)");
  265.         if (trace_on) trace_on = false; else trace_on = true;
  266.         break;
  267.        case eright: /* right */
  268.         text_right();
  269.         break;
  270.        case eup: /* arrow up */
  271.         text_up();
  272.         break;
  273.        case edown: /* arrow down */
  274.         text_down();
  275.         break;
  276.        case epageup:
  277.         tfy = tfy - 15;
  278.         if (tfy<1) {fner("Backup past top of file"); tfy = 1;}
  279.         text_move(tfx,tfy);
  280.         break;
  281.        case epagedown:
  282.         tfy = tfy + 15;
  283.         if (tfy>ngtxt) {fner("Advance past end of file"); tfy = ngtxt;}
  284.         text_move(tfx,tfy);
  285.         break;
  286.        case edelright:
  287.         changed = true;
  288.         text_right();
  289.         text_delete();
  290.         break;
  291.        case edeleol:
  292.         changed = true;
  293.         text_deleol();
  294.         break;
  295.        case eundeleol:
  296.         changed = true;
  297.         text_undeleol();
  298.         break;
  299.        case edelline:
  300.         changed = true;
  301.         text_deleteline();
  302.         break;
  303.       case edrawit:
  304.         window(1,1,79,24);
  305.         clrscr();
  306.         gotoxy(1,1);
  307.         scr_refresh();
  308.         gle_redraw();
  309.         if (netxt>0) text_showerror();
  310.         text_refresh();
  311.         break;
  312.       case eshowerror:
  313.         text_showerror();
  314.         text_refresh();
  315.         break;
  316.       case eundelline:
  317.         changed = true;
  318.         text_undelete();
  319.         break;
  320.       case eselect:
  321.         text_select();
  322.         break;
  323.       case ehelp: /* help */
  324.         do_help("SURFACE");
  325.         text_refresh();
  326.         break;
  327.       case esaveas:
  328.         text_saveas();
  329.         text_refresh();
  330.         break;
  331.       case esave: /* save file */
  332.         text_save();
  333.         changed = false;
  334.         break;
  335.       case efindnext:
  336.         text_findnext();
  337.         break;
  338.       case esearch: /* search for string */
  339.         text_search();
  340.         break;
  341.       case egraphmenu: /* graph mode  */
  342.         changed = true;
  343.         menu();
  344.         text_refresh();
  345.         break;
  346.       case eload:
  347.         { char infile[80]; char wildcard[80];
  348.         if (text_changed()) break;
  349.         if (read_command(infile,"Name of file to load <return for menu>")) break;
  350.         strcpy(wildcard,infile);
  351.         if (strlen(infile)==0) strcpy(wildcard,"*.sur");
  352.         if (strchr(wildcard,'*')!=NULL)
  353.             if (pick_file(infile,wildcard)) goto dontload;
  354.         text_free();
  355.         text_load(infile);
  356.         }
  357.         text_setwindow();
  358. dontload:    text_refresh();
  359.         break;
  360.       case ecut: /* control K , delete line, or block */
  361.         changed = true;
  362.         text_cut();
  363.         break;
  364.       case ebol:
  365.         text_move(1,tfy);
  366.         break;
  367.       case eeol:
  368.         text_move(strlen(line(tfy))+1,tfy);
  369.         break;
  370.       case eendoffile:
  371.         text_move(strlen(line(ngtxt))+1,ngtxt);
  372.         break;
  373.       case etopoffile:
  374.         text_move(1,1);
  375.         break;
  376.       case epaste: /* control Y , Yank line back, or block */
  377.         changed = true;
  378.         text_paste();
  379.         break;
  380.       case ereturn: /* carriage return */
  381.         changed = true;
  382.         text_return();
  383.         break;
  384.       case edelete: /* delete */
  385.         changed = true;
  386.         text_delete();
  387.         break;
  388.       default: /* normal key */
  389.         changed = true;
  390.         onmove = false;
  391.         if (c<26  && c!=9) {fner("Key has no affect"); break;}
  392.         if (c>200)  fner("Unimplemented command");
  393.         else normal_key(c);
  394.         break;
  395.      }
  396.     }
  397. }
  398. text_changed()
  399. {
  400.     int c;
  401.     if (!changed) return false;
  402.     for (;;) {
  403.         fner("Changes not saved,  save first ? (Y,N)");
  404.         c = text_inkey();
  405.         fner_clear();
  406.         if (c==eescape) return true;
  407.         if (tolower(c)=='n') return false;
  408.         if (tolower(c)=='y') {text_save(); return false;}
  409.     }
  410. }
  411. int text_expand(int n);
  412. text_expand(int n)
  413. {
  414.     char **a;
  415.     max_ngtxt = n;
  416.     a = myallocz(4*n);
  417.     if (gtxt!=NULL) {
  418.         memcpy(a,gtxt,ngtxt*4+4);
  419.         myfrees(gtxt,"textexpand");
  420.     }
  421.     gtxt = (char *(*)[]) a;
  422. }
  423. text_load(char *fname)
  424. {
  425. static char inbuff[200];
  426. FILE *fptr;
  427. int i;
  428. char emess[80];
  429.     changed = false;
  430.     strcpy(input_file,fname);
  431.     fptr = fopen(fname,"r");
  432.     if (fptr==NULL) {
  433.         if (errno == ENOFILE) {
  434.         sprintf(emess,"Input file does not exist (%s) ",fname);
  435.         fner(emess); 
  436.         delay(1000);
  437.         } else {
  438.             gprint("Unable to open input file {%s},\n (press return) \n",fname);
  439.             text_inkey(); perror("Reason");
  440.             fner("Press return to continue");
  441.             text_inkey();
  442.         }
  443.     } else {
  444.      for (;!feof(fptr);) {
  445.         if (fgets(inbuff,200,fptr)!=NULL) {
  446.             i = strlen(inbuff);
  447.             if (inbuff[i-1]=='\n') inbuff[i-1] = 0;
  448.             ngtxt++;
  449.             if (ngtxt>(max_ngtxt-300)) {
  450.                 text_expand(2*(ngtxt+500));
  451.             }
  452.             (*gtxt)[ngtxt] = myalloc(i+1);
  453.             strcpy((*gtxt)[ngtxt],inbuff);
  454.         }
  455.      }
  456.      fclose(fptr);
  457.     }
  458.     if (ngtxt==0) {
  459.         (*gtxt)[++ngtxt] = sdup("begin surface");
  460.         (*gtxt)[++ngtxt] = sdup("    data test.z");
  461.         (*gtxt)[++ngtxt] = sdup("end surface");
  462.     }
  463.     if (ngtxt==1) (*gtxt)[++ngtxt] = sdup("");
  464.     tfx = 1;
  465.     tfy = 1;
  466. }
  467. char errgle[90];
  468. int dont_clear;
  469. gle_abort(char *s)
  470. {
  471.     d_tidyup();
  472.     delay(1000);
  473.     dont_clear = true;
  474.     window(1,1,80,25);
  475.     scr_norm();
  476.     clrscr();
  477.     printf("\n\n\n\n %s \nGle is aborting, Attempting to save file in abort.gle\n",s);
  478.     strcpy(input_file,"abort.gle");
  479.     text_save();
  480.     printf("File is now saved (hopefully)\n");
  481.     if (strstr(s,"alloc")!=NULL  || strstr(s,"Init")!=NULL) {
  482.         printf("\nGLE is short of memory!!\n\n");
  483.         printf("If you are using very large datasets you should try\n");
  484.         printf("the BIGFILE option, otherwise you probably have too\n");
  485.         printf("many memory resident programs on your pc and to make GLE work\n");
  486.         printf("you should remove these from your CONFIG.SYS and AUTOEXEC.BAT\n");
  487.         printf("\n  (make coppies of these files before altering them)\n");
  488.     }
  489.     exit(1);
  490. }
  491. text_save()
  492. {
  493. FILE *fptr;
  494. int i;
  495.     changed = false;
  496.     fner("Saving file");
  497.     unlink("glegle.bak");
  498.     unlink("glegle.tmp");
  499.     fptr = fopen("glegle.tmp","w");
  500.     if (fptr==NULL) perror("Unable to open output file GLEGLE.TMP");
  501.     for (i=1;i<=ngtxt;i++) {
  502.         if (fputs(line(i),fptr)==EOF
  503.             && i<ngtxt &&  (strlen(line(i)) > 0) )
  504.             printf("Unable to write line %d {%s} \n",i,line(i));
  505.         fputs("\n",fptr);
  506.     }
  507.     if (fclose(fptr)!=0) perror("Unable to close output file GLEGLE.TMP");
  508. #ifdef __TURBOC__
  509.     if (rename(input_file,"glegle.bak")!=0) ; /*
  510.         perror("Unable to rename input file to glegle.bak"); */
  511. #endif
  512.     if (rename("glegle.tmp",input_file)!=0) perror("Unable to rename GLEGLE.TMP to output file");
  513.     fner_clear();
  514. }
  515. text_bol()
  516. {
  517.     tfx = 1;
  518.     text_move(tfx,tfy);
  519. }
  520. text_eol()
  521. {
  522.     tfx = strlen(line(tfy))+1;
  523.     text_move(tfx,tfy);
  524. }
  525. text_left()
  526. {
  527.     onmove = false;
  528.     if (tfx==1) {
  529.         if (tfy==1) return;
  530.         tfy--; tfx = strlen(line(tfy))+1;
  531.     } else tfx--;
  532.     text_move(tfx,tfy);
  533. }
  534. text_right()
  535. {
  536.     onmove = false;
  537.     if (tfx== 1+strlen(line(tfy)) ) {
  538.         if (tfy==ngtxt) return;
  539.         tfy++; tfx = 1;
  540.     } else tfx++;
  541.     text_move(tfx,tfy);
  542. }
  543. text_up()
  544. {
  545.     if (tfy==1) {fner("Backup past end of file"); return;}
  546.     if (!onmove) {
  547.         onmove = true;
  548.         move_pos = scr_tab(line(tfy),tfx);
  549.     }
  550.     tfy--;
  551.     scr_negtab(line(tfy),move_pos,&tfx,&ii);
  552.     text_move(tfx,tfy);
  553. }
  554. text_down()
  555. {
  556.     if (tfy==ngtxt) {fner("Advace past end of file"); tfy--;}
  557.     if (!onmove) {
  558.         onmove = true;
  559.         move_pos = scr_tab(line(tfy),tfx);
  560.     }
  561.     tfy++;
  562.     scr_negtab(line(tfy),move_pos,&tfx,&ii);
  563.  /*gotoxy(5,9);gprint("negtab line=%d m=%d f=%d \n",tfy,move_pos,tfx);*/
  564.     text_move(tfx,tfy);
  565. }
  566. text_return()
  567. {
  568.     strcpy(gbuff,line(tfy)+tfx-1);
  569.     ncpy(gbuff2,line(tfy),tfx-1);
  570.     lineset(tfy,gbuff2);
  571.     lineinsert(tfy+1,gbuff);
  572.     text_right();
  573. }
  574. char line_buff[255];
  575. text_undelete()
  576. {
  577.     lineinsert(tfy,line_buff);
  578.     text_move(tfx,tfy);
  579. }
  580. text_undeleol()
  581. {
  582.     strcpy(gbuff2,line(tfy)+tfx-1);
  583.     ncpy(gbuff,line(tfy),tfx-1);
  584.     strcat(gbuff,line_buff);
  585.     lineinsert(tfy,gbuff);
  586.     lineset(tfy+1,gbuff2);
  587.     text_move(tfx,tfy);
  588. }
  589. text_saveas()
  590. {
  591.     if (read_command(input_file,"New gle file name ")) return;
  592.     text_save();
  593. }
  594. char search_string[100];
  595. text_search()
  596. {
  597.     if (read_command(search_string,"Enter string to search for ")) return;
  598.     strlwr(search_string);
  599.     text_findnext();
  600. }
  601. text_findnext()
  602. {
  603.     int i;
  604.     char fline[100];
  605.     char *p;
  606.     for (i=tfy+1; i<=ngtxt; i++) {
  607.         ncpy(fline,line(i),90);
  608.         strlwr(fline);
  609.         p = strstr(fline,search_string);
  610.         if (p!=NULL) {
  611.             tfy = i; tfx = p - &fline[0] + 1;
  612.             text_move(tfx,tfy);
  613.             return;
  614.         }
  615.     }
  616.     fner("String was not found");
  617. }
  618. text_select()
  619. {
  620.     selx = tfx;    sely = tfy;
  621.     text_move(tfx,tfy);
  622. }
  623. int swapint(int *a,int *b);
  624. swapint(int *a, int *b)
  625. {
  626.     int c;
  627.     c = *a; *a = *b; *b = c;
  628. }
  629. text_cut()
  630. {
  631.     int i,x1=selx,y1=sely,x2=tfx,y2=tfy;
  632.     if (selx==0 && sely==0) return;
  633.     if (y1==y2)  if (x2<x1) swapint(&x1,&x2);
  634.     if (y2<y1) { swapint(&x1,&x2); swapint(&y1,&y2); }
  635.     if (ncut>0) {
  636.         myfrees(ctxt,"textcut");
  637.         for (i=1;i<=ncut;i++) myfree((*ctxt)[i]);
  638.     }
  639.     ctxt = myalloc((y2-y1+3)*4);
  640.     ncut = 1;
  641.     if (y1==y2) {
  642.         ncpy(gbuff,line(y1)+x1-1,x2-x1);
  643.         (*ctxt)[1] = sdup(gbuff);
  644.         ncpy(gbuff,line(y1),x1-1);
  645.         strcat(gbuff,line(y1)+x2-1);
  646.         lineset(y1,gbuff);
  647.         text_move(x1,y1);
  648.         return;
  649.     }
  650.     for (i=y1+1;i<y2;i++) (*ctxt)[++ncut] = sdup(line(i));
  651.     for (i=y1+1;i<y2;i++) linedelete(y1+1);
  652.     (*ctxt)[1] = sdup(line(y1)+x1-1);
  653.     ncpy(gbuff2,line(y1+1),x2-1);
  654.     (*ctxt)[++ncut] = sdup(gbuff2);
  655.     ncpy(gbuff,line(y1),x1-1);
  656.     strcat(gbuff,line(y1+1)+x2-1);
  657.     lineset(y1,gbuff);
  658.     linedelete(y1+1);
  659.     text_move(x1,y1);
  660. }
  661. text_paste()
  662. {
  663.     int i;
  664.     if (ncut==0) return;
  665.     if (ncut==1) {
  666.         ncpy(gbuff,line(tfy),tfx-1);
  667.         strcat(gbuff,(*ctxt)[1]);
  668.         strcat(gbuff,line(tfy)+tfx-1);
  669.         lineset(tfy,gbuff);
  670.         text_move(tfx+strlen((*ctxt)[1]),tfy);
  671.         return;
  672.     }
  673.     ncpy(gbuff,line(tfy),tfx-1);
  674.     strcat(gbuff,(*ctxt)[1]);
  675.     strcpy(gbuff2,(*ctxt)[ncut]);
  676.     strcat(gbuff2,line(tfy)+tfx-1);
  677.     lineset(tfy,gbuff);
  678.     lineinsert(tfy+1,gbuff2);
  679.     for (i=ncut-1;i>1;i--) lineinsert(tfy+1, (*ctxt)[i]);
  680.     text_move(strlen((*ctxt)[ncut])+1,tfy+ncut-1);
  681. }
  682. text_deleol()
  683. {
  684.     if (ngtxt+1==tfy) return;
  685.     strcpy(line_buff,line(tfy)+tfx-1);
  686.     ncpy(gbuff,line(tfy),tfx-1);
  687.     if (tfy<ngtxt) strcat(gbuff,line(tfy+1));
  688.     lineset(tfy,gbuff);
  689.     if (ngtxt<=tfy) {
  690.         gbuff[0] = 0;
  691.         lineinsert(tfy+1,gbuff);
  692.     } else     linedelete(tfy+1);
  693.     text_move(tfx,tfy);
  694. }
  695. text_deleteline()
  696. {
  697.     if (ngtxt==1) return;
  698.     strcpy(line_buff,line(tfy));
  699.     linedelete(tfy);
  700.     if (ngtxt<tfy) {
  701.         gbuff[0] = 0;
  702.         lineinsert(tfy,gbuff);
  703.     }
  704.     text_move(tfx,tfy);
  705. }
  706. text_delete()
  707. {
  708.     int oldx;
  709.     if (tfx==1) {
  710.         if (tfy==1) {fner("Backup past top of file"); return;}
  711.         text_left();
  712.         oldx = tfx;
  713.         strcpy(gbuff2,line(tfy));
  714.         text_deleteline();
  715.         strcat(gbuff2,line(tfy));
  716.         lineset(tfy,gbuff2);
  717.         tfx = oldx;
  718.         text_move(tfx,tfy);
  719.         return;
  720.     }
  721.     ncpy(gbuff,line(tfy),tfx-2);
  722.     strcat(gbuff,line(tfy)+tfx-1);
  723.     tfx--;
  724.     lineset(tfy,gbuff);
  725.     text_move(tfx,tfy);
  726. }
  727. text_setwindow()
  728. {
  729.     if (tfy>w_top-4 || tfy<w_bot+4) w_top = tfy - (w_len-1)/2;
  730.     if (w_top<1) w_top = 1;
  731.     w_bot = w_top + w_len - 1;
  732. }
  733. text_refresh()
  734. {
  735.     char doubleline[90];
  736.     int e,i;
  737.     iserr = true; /* so that function keys appear at bottom */
  738.     window(1,1,80,25);
  739.     scr_norm();
  740.     clrscr();
  741.     gotoxy(1,1); wprintf("Memory Used=%ld  Free=%ld   SURFACE V3.3a  Current file={%s}"
  742.         ,mem_total(),coreleft(),input_file);
  743.  
  744.     memset(doubleline,HLINECHAR,80);
  745.     doubleline[80] = 0;
  746.     gotoxy(1,2); cputs(doubleline);
  747.  
  748.     fner_clear();
  749.     window(2,3,79,23);
  750.     gotoxy(1,1);
  751.     e = w_bot;
  752.     if (e>ngtxt) e = ngtxt;
  753.     for (i=w_top;i<=e;i++) {
  754.         gotoxy(1,i-w_top+1);
  755.         cputs( sline(i) );
  756.     }
  757.     if (e<w_bot) {
  758.         gotoxy(1,i-w_top+1);
  759.         cputs("[EOF]");
  760.     }
  761.     gotoxy(scr_tab(line(tfy),tfx), tfy - w_top + 1);
  762. }
  763. /*---------- move cursor to file coloumn x, line y */
  764. text_move(int x,int y)
  765. {
  766.     tfx = x;
  767.     tfy = y;
  768.     if (tfy>ngtxt) tfy = ngtxt;
  769.     if (tfy<1) tfy = 1;
  770.     if (tfx>strlen(line(tfy))+1) tfx = strlen(line(tfy))+1;
  771.     if (tfx<1) tfx = 1;
  772.     if (tfy<(w_top+5) || tfy>(w_bot-5)) {
  773.         if (tfy<(w_top-25) || tfy>(w_bot+25)) {
  774.             text_setwindow();
  775.             text_refresh();
  776.         } else {
  777.             text_scroll();
  778.         }
  779.     }
  780.     gotoxy(scr_tab(line(tfy),tfx), tfy - w_top + 1);
  781. }
  782. restofline(int y,int x)
  783. {
  784.     int sx;
  785.     if (x <= strlen(line(y))) {
  786.         sx = scr_tab(line(y),x);
  787.         gotoxy(sx,y-w_top + 1);
  788.         clreol();
  789.         cputs(sline(y)+sx-1);
  790.         gotoxy(scr_tab(line(y),tfx), y - w_top + 1);
  791.     }
  792. }
  793. fixline(int y)
  794. {
  795.     gotoxy(1,y-w_top + 1);
  796.     clreol();
  797.     cputs(sline(y));
  798. }
  799. scrinsert(int y)
  800. {
  801.     gotoxy(1,y-w_top + 1);
  802.     insline();
  803.     cputs(sline(y));
  804. }
  805. text_scroll()
  806. {
  807.     int n,i;
  808.     n = w_top - tfy + 5;
  809.     /* printf("n %d, w_top %d  tfy %d \n",n,w_top,tfy); */
  810.     if (w_top-n<1) n = w_top - 1;
  811.     if (n>0) {
  812.         for (i=0;i<n;i++) text_scroll_down();
  813.         return;
  814.     }
  815.     n = tfy - w_bot + 5;
  816.     if (w_bot+n>ngtxt) n = ngtxt - w_bot;
  817.     if (n>0) {
  818.         for (i=0;i<n;i++) text_scroll_up();
  819.         return;
  820.     }
  821. }
  822. /* ------------------------ Find screen position given x pos in string */
  823. scr_tab(char *s, int x)
  824. {
  825.     int p=0,i=0;
  826.     for (;*s!=0 && i<(x-1);i++,s++) {
  827.         if (*s==9)  p = (p/8)*8+8;
  828.         else       p++;
  829.     }
  830.     return ++p;
  831. }
  832. /*------------------------- Find file x position given x pos on screen */
  833. /* and sets scrx to the correct screen position (if in middle of tab) */
  834. scr_negtab(char *s, int x, int *fpos, int *scrx)
  835. {
  836.     int last_pos=0,i;
  837.     *fpos=0;
  838.     *scrx = 0;
  839.  
  840.     for (i=0;*s!=0;s++,i++) {
  841.         if (*s==9) *scrx = (*scrx/8)*8+8;
  842.         else (*scrx)++;
  843.         if ((*scrx+1)>x) {
  844.             *fpos = i+1;
  845.             *scrx = last_pos;
  846.             return;
  847.         }
  848.         last_pos = *scrx + 1;
  849.     }
  850.     if (*scrx==0) (*scrx)++;
  851.     *fpos = i+1;
  852.     if (i==0) *fpos = 1;
  853. }
  854. text_scroll_down()
  855. {
  856.     gotoxy(1,1);insline();
  857.     w_top--;w_bot--;
  858.     fixline(w_top);
  859. }
  860. text_scroll_up()
  861. {
  862.     char ss[90];
  863.     gotoxy(1,1); delline();
  864.     w_top++; w_bot++;
  865.     fixline(w_bot);
  866. }
  867. scrdeleteline(int y)
  868. {
  869.     gotoxy(1, y - w_top + 1);
  870.     delline();
  871.     fixline(w_bot);
  872. }
  873. char *function_bar(void);
  874. fner_clear()
  875. {
  876.     if (iserr==false) return;
  877.     if (dont_clear) return;
  878.     window(1,1,80,25);
  879.     gotoxy(1,25);
  880.     scr_grey();
  881.     clreol();
  882.     gotoxy(2,25);
  883.     cputs(function_bar());
  884.     scr_norm();
  885.     iserr = false;
  886.     window(2,3,79,23);
  887. }
  888. fner(char *s)
  889. {
  890.     if (dont_clear) return;
  891.     scr_savexy();
  892.     iserr = true;
  893.     window(1,1,80,25);
  894.     gotoxy(1,25);
  895.     scr_inv();
  896.     clreol();
  897.     gotoxy(2,25);
  898.     cputs(s);
  899.     scr_norm();
  900.     scr_restorexy();
  901.     scr_refresh();
  902. }
  903. int read_command(char *ans,char *ques)
  904. {
  905.     int rr;
  906.     iserr = true;
  907.     window(1,1,80,25);
  908.     gotoxy(1,24);
  909.     scr_inv();
  910.     clreol();
  911.     gotoxy(2,24);
  912.     cputs(ques);
  913.     rr = read_str(ans);
  914.     gotoxy(1,24);
  915.     scr_norm();
  916.     clreol();
  917.     window(2,3,79,23);
  918.     text_move(tfx,tfy);
  919.     return rr;
  920. }
  921. int read_input(char *ans,char *ques)
  922. {
  923.     int rr;
  924.     iserr = true;
  925.     clreol();
  926.     cputs(ques);
  927.     rr = read_str(ans);
  928.     wprintf("\n");
  929.     return rr;
  930. }
  931.  
  932. int read_str(char *s)
  933. {
  934.     int c,cx=0;
  935.     char mbuff[80];
  936.     *s = 0;
  937.     for (;;) {
  938.      c = text_inkey();
  939.      switch (c) {
  940.        case eescape: /* ESCAPE */
  941.        case equit: /* control c */
  942.         return true;
  943.        case eleft: /* left */
  944.         if (cx <= 0) break;
  945.         cx--;
  946.         scr_left(1);
  947.         break;
  948.        case eright: /* right */
  949.         if (cx >= strlen(s)) break;
  950.         cx++;
  951.         scr_right(1);
  952.         break;
  953.        case eup: /* arrow up */
  954.        case edown: /* arrow down */
  955.       case ehelp: /* f1 help */
  956.         break;
  957.       case ereturn: /* carriage return */
  958.         return false;
  959.       case edelete: /* delete */
  960.         if (strlen(s)==0) break;
  961.         if (cx<1) break;
  962.         ncpy(mbuff,s,cx-1);
  963.         strcat(mbuff,s + cx);
  964.         strcpy(s,mbuff);
  965.         cx--;
  966.         scr_left(1);
  967.         cputs(s + cx);
  968.         putch(' ');
  969.         scr_left(strlen(s+cx)+1);
  970.         break;
  971.       case eshowerror:
  972.       case edrawit:
  973.         break;
  974.       default: /* normal key */
  975.         if (c<26  && c!=9) {fner("Key has no affect"); break;}
  976.         if (c>200)  fner("Unimplemented command");
  977.         else {
  978.             ncpy(mbuff,s,cx);
  979.             mbuff[cx] = c; mbuff[cx+1] = 0;
  980.             strcat(mbuff,s + cx);
  981.             strcpy(s,mbuff);
  982.             cputs(s + cx);
  983.             cx++;
  984.             scr_left(strlen(s+cx));
  985.         }
  986.         break;
  987.        }
  988.      }
  989. }
  990. normal_key(int c)
  991. {
  992.     static char lbuff[255];
  993.     if (ngtxt+1==tfy) {
  994.         text_up();
  995.         text_eol();
  996.         text_return();
  997.     }
  998.     ncpy(lbuff,line(tfy),tfx-1);
  999.     lbuff[tfx-1] = c; lbuff[tfx]=0;
  1000.     strcat(lbuff,line(tfy)+tfx-1);
  1001.     tfx++;
  1002.     lineset(tfy,lbuff);
  1003. }
  1004. text_showerror()
  1005. {
  1006.     int i,n;
  1007.     if (netxt==0) {
  1008.         fner("There were no errors, press return");
  1009.         text_inkey();
  1010.         return;
  1011.     }
  1012.     clrscr();
  1013.     n = netxt;
  1014.     if (n>20) n = 17;
  1015.     for (i=1;i<=n;i++) {
  1016.         gotoxy(3,i);
  1017.         cputs( (*etxt)[i] );
  1018.     }
  1019.     gotoxy(1,20); cputs("Press any key to continue");
  1020.     text_inkey();
  1021. }
  1022. #ifndef unix
  1023. void wprintf(va_list arg_list, ...)
  1024. /* Prints to the window */
  1025. {
  1026.      va_list arg_ptr;
  1027.      char *format;
  1028.     char output[200];
  1029.  
  1030.      va_start(arg_ptr, arg_list);
  1031.      format = arg_list;
  1032.      vsprintf(output, format, arg_ptr);
  1033. #ifdef __TURBOC__
  1034.     printf(output);
  1035. #else
  1036.     cputs(output);
  1037. #endif
  1038. }
  1039. #endif
  1040.